#ifndef _NE_SINGLETON_H_
#define _NE_SINGLETON_H_

#include <neinit.h>

namespace ne
{
    template<typename T> class Singleton
    {
        public:
            virtual ~Singleton()
            {
                assert(mpInstance);
                mpInstance = 0;
            }

        public:
            static T& Instance()
            {
                assert(mpInstance);
                return *mpInstance;
            }

            static T* InstancePtr()
            {
                return mpInstance;
            }

        protected:
            Singleton()
            {
                assert(!mpInstance);
#if defined( _MSC_VER ) && _MSC_VER < 1200
                int offset = (int)(T*)1 - (int)(Singleton<T>*)(T*)1;
                mpInstance = (T*)((int)this + offset);
#else
                /* Here can't use dynamic_cast<>
                   Because this Construct earlier than Child
                   dynamic_cast will return NULL
                */
                mpInstance = static_cast<T*>(this);
#endif
            }

        private:
            Singleton(const Singleton<T> &);

            Singleton& operator = (const Singleton<T> &);

        protected:
            static T* mpInstance;
    };

    template<typename T> T* Singleton<T>::mpInstance = 0;
}

#endif
